package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"github.com/google/shlex"
	"io"
	"os"
	"regexp"
	"strconv"
	"strings"
)

type multipathInfo struct {
	wwid              string
	size              string
	features          string
	hwhandler         string
	write_permission  string
	scheduling_policy string
	prio              string
	alias             string
	dm_device_name    string
	vendor            string
	status            string
	path              map[string]*pathInfo
}

type pathInfo struct {
	path          string
	devnode       string
	major_minor   string
	dm_status     string
	path_status   string
	online_status string
}

func main() {
	tempParsingData := make(map[string]string)
	pathParsingData := make(map[string]string)
	var parsedData []map[string]string
	var paths []pathInfo
	thisIsANewBlock := false
	pathIndex := 0

	filePth := "E:/application/go_learning/multipath/result.txt"
	f, err := os.Open(filePth)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	bfRd := bufio.NewReader(f)
	for {
		line, err := bfRd.ReadBytes('\n')
		if byteMatchResult, _ := regexp.Match(`^\w`, line); byteMatchResult {
			if byteMatchResult, _ := regexp.Match(`^size`, line); byteMatchResult {
				a, _ := shlex.Split(string(line))
				tempParsingData["size"] = strings.Split(a[0], "=")[1]
				tempParsingData["features"] = strings.Split(a[1], "=")[1]
				tempParsingData["hwhandler"] = strings.Split(a[2], "=")[1]
				tempParsingData["write_permission"] = strings.Split(a[3], "=")[1]
			} else {
				thisIsANewBlock = true

				if len(tempParsingData) > 0 && thisIsANewBlock {
					parsedData = append(parsedData, tempParsingData)
					tempParsingData = make(map[string]string)
					thisIsANewBlock = false
				}

				if byteMatchResult, _ := regexp.Match(`^[\w]{33}`, line); byteMatchResult {
					a, _ := shlex.Split(string(line))
					tempParsingData["wwid"] = a[0]
					tempParsingData["dm_device_name"] = a[1]
					tempParsingData["vendor"] = a[2]
				} else if byteMatchResult, _ := regexp.Match(`^.*\([\w]{33}\)`, line); byteMatchResult {
					a, _ := shlex.Split(string(line))
					tempParsingData["alias"] = a[0]
					tempParsingData["wwid"] = strings.Trim(a[1], "()")
					tempParsingData["dm_device_name"] = a[2]
					tempParsingData["vendor"] = a[3]
				}
			}
		} else {
			if byteMatchResult, _ := regexp.Match(`.*-\+-`, line); byteMatchResult {
				a, _ := shlex.Split(string(line))
				tempParsingData["scheduling_policy"] = strings.Split(a[1], "=")[1]
				tempParsingData["prio"] = strings.Split(a[2], "=")[1]
				tempParsingData["status"] = strings.Split(a[3], "=")[1]
				pathIndex = 0
			} else if byteMatchResult, _ := regexp.Match(`.*-`, line); byteMatchResult {
				a, _ := shlex.Split(string(line))
				pathParsingData = make(map[string]string)
				pathParsingData["path"] = a[1]
				pathParsingData["devnode"] = a[2]
				pathParsingData["major:minor"] = a[3]
				pathParsingData["dm_status"] = a[4]
				pathParsingData["path_status"] = a[5]
				pathParsingData["online_status"] = a[6]
				paths = append(paths, pathInfo{
					path:          a[1],
					devnode:       a[2],
					major_minor:   a[3],
					dm_status:     a[4],
					path_status:   a[5],
					online_status: a[6],
				})
				index := strconv.Itoa(pathIndex)
				pathParsing, _ := json.Marshal(pathParsingData)
				paths, _ := json.Marshal(paths)
				tempParsingData["path"+index] = string(pathParsing)
				tempParsingData["path"] = string(paths)
				pathIndex = pathIndex + 1
				//fmt.Println(m)
			}
		}

		//遇到任何错误立即返回，并忽略 EOF 错误信息
		if err != nil {
			if err == io.EOF {
				break
			}
		}
	}
	if len(tempParsingData) > 0 {
		parsedData = append(parsedData, tempParsingData)
		tempParsingData = make(map[string]string)
	}
	fmt.Println(parsedData)

	for i := 0; i < len(parsedData); i++ {
		fmt.Println(i, parsedData[i])
		for k, v := range parsedData[i] {
			fmt.Println(k, v)
		}
	}
}
